class Menu
  attr_reader :options_stack
  
  CHECK_KEEP_SETTINGS_TIME = 6
  OPTION_TEXT_HEIGHT = 18
  OPTION_HEIGHT_MARGIN = 4
  OPTION_HEIGHT_PADDING = 12
  OPTION_WIDTH_MARGIN = 12
  OPTION_WIDTH_PADDING = 24
  SLIDER_WIDTH = 8
  SLIDER_COLOR = 0xdd559955
  BACK_COLOR = 0xdd559955
  OPTION_BACK_COLOR_TOP = 0xeeaaaaaa
  OPTION_BACK_COLOR_BOTTOM = 0xee7F7F7F
  OPTION_BACK_COLOR_SELECTED_TOP = 0xffffffaa
  OPTION_BACK_COLOR_SELECTED_BOTTOM = 0xffffffaa
  OPTION_TEXT_COLOR = 0xff000000
  PLAYER_SUMMARY_WIDTH = 290
  
  def initialize(window)
    @window = window
    @screen_width = @window.width
    @screen_width /= 2 if @screen_width > 1280
    @back_color = 0xffaaaaaa
    @restart = false
    @@font = Gosu::Font.new(window, Gosu::default_font_name, OPTION_TEXT_HEIGHT)
    @options = []
    if $check_keep_screen_dimensions
      @check_keep_screen_dimensions_timer = CHECK_KEEP_SETTINGS_TIME
      @options << KeepSettingsOption.new
    end
    @options << QuickStartOption.new << NewGameOption.new << InstructionsOption.new << OptionsOption.new << AboutOption.new << ExitOption.new
    @options_stack = [@options]
    hide_player_summary
    calculate_dimensions
  end
  
  def calculate_dimensions
    @option_width = 0
    @back_height = OPTION_HEIGHT_PADDING
    @options.each do |o|
      @option_width = o.min_width if @option_width < o.min_width
      @back_height += o.height + OPTION_HEIGHT_PADDING
    end
    @back_width = @option_width + OPTION_WIDTH_PADDING * 2
    
    @selected_option_index = 0
    until @options[@selected_option_index].selectable
      @selected_option_index += 1
    end
    
    @player_summary_height = OPTION_HEIGHT_PADDING
    Game::MAX_PLAYERS.times do
      @player_summary_height += OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2 + OPTION_HEIGHT_PADDING
    end
    @player_summary_width = PLAYER_SUMMARY_WIDTH
  end
  
  def update
    if @check_keep_screen_dimensions_timer 
      if milliseconds > (@prev_milliseconds || 0) + 1000
        if @check_keep_screen_dimensions_timer > 0
          @check_keep_screen_dimensions_timer -= 1
          @options.each do |o|
            o.text = "Keep these settings (#{@check_keep_screen_dimensions_timer})" if o.text.match(/Keep these settings/)
          end
        elsif @check_keep_screen_dimensions_timer == 0
          main_restart(true)
        end
        @prev_milliseconds = milliseconds
      end
    end
  end
  
  def deactivate_settings_check_timer
    @check_keep_screen_dimensions_timer = nil
    @options.reject! { |o| o.class.to_s == "KeepSettingsOption" }
    calculate_dimensions
  end
  
  def draw
    unless $game.game_started
      ($game.height / 480 + 1).times do |y|
        ($game.width / 640 + 1).times do |x|
          Images["media/space.png"].draw(x * 640, y * 480, ZOrder::Menu)
        end
      end
      Images["media/menu_bottom_left.png"].draw(0, $game.height - Images["media/menu_bottom_left.png"].height, ZOrder::Menu)
      Images["media/menu_bottom_right.png"].draw($game.width - Images["media/menu_bottom_right.png"].width, $game.height - Images["media/menu_bottom_left.png"].height, ZOrder::Menu)
    end
    
    if @show_player_summary
      temp_x = @screen_width/2 - @back_width - OPTION_WIDTH_PADDING / 2
    else
      temp_x = @screen_width/2 - @back_width/2
    end
    
    temp_y = @window.height/2 - @back_height/2
    @window.draw_quad(temp_x, temp_y, BACK_COLOR, 
                        temp_x + @back_width, temp_y, BACK_COLOR, 
                        temp_x, temp_y + @back_height, BACK_COLOR, 
                        temp_x + @back_width, temp_y + @back_height, BACK_COLOR, ZOrder::Menu)
    
    temp_x += OPTION_WIDTH_PADDING
    temp_y += OPTION_HEIGHT_PADDING
    @options.each_with_index do |o, i|
      o.draw(temp_x, temp_y, @option_width, i == @selected_option_index)
      temp_y += o.height + OPTION_HEIGHT_PADDING
    end
    
    if @options[@selected_option_index].help
      temp_y = @window.height - OPTION_HEIGHT_PADDING - @options[@selected_option_index].help.size
      help_bottom = temp_y
      help_width = 0
      @options[@selected_option_index].help.each do |l|
        help_width = @@font.text_width(l) + 2 * OPTION_WIDTH_PADDING if @@font.text_width(l) + 2 * OPTION_WIDTH_PADDING > help_width
      end
      temp_x = @screen_width / 2 - help_width / 2
      temp_y -= OPTION_HEIGHT_PADDING
      @options[@selected_option_index].help.each do |l|
        @@font.draw_rel(l, @screen_width/2, temp_y, ZOrder::Menu, 0.5, 1, 1, 1, OPTION_TEXT_COLOR)
        temp_y -= OPTION_TEXT_HEIGHT + OPTION_HEIGHT_PADDING / 2
      end
      
      @window.draw_quad(temp_x, temp_y, BACK_COLOR, 
                          temp_x + help_width, temp_y, BACK_COLOR, 
                          temp_x, help_bottom, BACK_COLOR, 
                          temp_x + help_width, help_bottom, BACK_COLOR, ZOrder::Menu - 1)
      
    end
    
    if @show_player_summary
      temp_x = @screen_width/2 + OPTION_WIDTH_PADDING / 2
      temp_y = @window.height/2 - @player_summary_height/2
      
      @window.draw_quad(temp_x, temp_y, BACK_COLOR, 
                        temp_x + @player_summary_width, temp_y, BACK_COLOR, 
                        temp_x, temp_y + @player_summary_height, BACK_COLOR, 
                        temp_x + @player_summary_width, temp_y + @player_summary_height, BACK_COLOR, ZOrder::Menu)
      
      temp_x += OPTION_WIDTH_PADDING
      temp_y += OPTION_HEIGHT_PADDING
      
      (0..Game::MAX_PLAYERS - 1).each do |n|
        if GameConfig["unit#{n}_controller"] != "None"
          #o.draw(temp_x, temp_y, @option_width, i == @selected_option_index)
          color_top = Menu::OPTION_BACK_COLOR_TOP
          color_bottom = Menu::OPTION_BACK_COLOR_BOTTOM
          
          opt_width = @player_summary_width - 2 * OPTION_WIDTH_PADDING
          
          $game.draw_quad(temp_x-2, temp_y-2, GameConfig["unit#{n}_uniform_color"], 
                            temp_x + opt_width+2, temp_y-2, GameConfig["unit#{n}_uniform_color"], 
                            temp_x-2, temp_y + OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2+2, GameConfig["unit#{n}_uniform_color"], 
                            temp_x + opt_width+2, temp_y + OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2+2, GameConfig["unit#{n}_uniform_color"], ZOrder::Menu)
          
          $game.draw_quad(temp_x, temp_y, color_top, 
                            temp_x + opt_width, temp_y, color_top, 
                            temp_x, temp_y + OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2, color_bottom, 
                            temp_x + opt_width, temp_y + OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2, color_bottom, ZOrder::Menu)
          
          text = "#{GameConfig["unit#{n}_controller"]}, "
          text.gsub!(/ \(left\)/, "")
          text.gsub!(/ \(right\)/, "")
          text += "team #{GameConfig["unit#{n}_team"]}, health #{GameConfig["unit#{n}_health"]}"
          @@font.draw_rel(text, temp_x - OPTION_WIDTH_PADDING + @player_summary_width/2, temp_y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 0.5, 0, 1, 1, OPTION_TEXT_COLOR)
        end
        temp_y += OPTION_TEXT_HEIGHT + OPTION_HEIGHT_MARGIN * 2 + OPTION_HEIGHT_PADDING
      end
    end
  end
  
  def change_selection(dir)
    ###refactor this
    @selected_option_index += dir
    @selected_option_index = @options.size - 1 if @selected_option_index < 0
    @selected_option_index = 0 if @selected_option_index > @options.size - 1
    until @options[@selected_option_index].selectable
      @selected_option_index += dir
      @selected_option_index = @options.size - 1 if @selected_option_index < 0
      @selected_option_index = 0 if @selected_option_index > @options.size - 1
    end
  end
  
  def handle_selection(val = 1)
    @options[@selected_option_index].handle_selection(val)
  end
  
  def new_options(opts)
    hide_player_summary
    @options_stack.push opts
    @options = opts
    calculate_dimensions
    @selected_option_index = 0
    until @options[@selected_option_index].selectable
      @selected_option_index += 1
    end
  end
  
  def back
    if @options_stack.size == 1
      $game.close
    else
      @options_stack.pop
      @options = @options_stack.last
      calculate_dimensions
      hide_player_summary if @options_stack.size == 1 ###
    end
    
    if @restart
      main_restart
    end
  end
  
  def go_to_main_menu
    until @options_stack.size == 1
      back
    end
  end
  
  def go_to_game_over
    go_to_main_menu
    opts = []
    opts << TeamWonOption.new
    opts << ScoreboardOption.new
    opts << GameOverBackOption.new
    new_options(opts)
  end
  
  def add_main_option(option)
    unless @options_stack[0].include?(option)
      @options_stack[0].unshift(option)
      calculate_dimensions
    end
  end
  
  def remove_main_option(option_class)
    @options_stack[0].reject! { |o| o.class == option_class }
    calculate_dimensions
  end
  
  def handle_escape
    back
  end
  
  def self.font
    @@font
  end
  
  def show_player_summary
    @show_player_summary = true
  end
  
  def hide_player_summary
    @show_player_summary = false
  end
  
  def restart
    @restart = true
  end
end

class MenuOption
  attr_reader :name, :selectable, :height, :min_width, :slider, :toggle, :value, :sub_menus, :help
  attr_accessor :text
  def initialize
  end
  def handle_selection(val)
  end
end

class RegularOption < MenuOption
  def initialize(text)
    @text = text
    @selectable = true
    @text_height = Menu::OPTION_TEXT_HEIGHT
    @text_width = Menu.font.text_width(@longest_possible_value || @text)
    @height = Menu::OPTION_TEXT_HEIGHT + Menu::OPTION_HEIGHT_MARGIN * 2
    @min_width = @text_width + Menu::OPTION_WIDTH_MARGIN*2
  end
  def handle_selection(val)
  end
  def draw(x, y, width, selected)
    color_top = Menu::OPTION_BACK_COLOR_TOP if !selected
    color_bottom = Menu::OPTION_BACK_COLOR_BOTTOM if !selected
    color_top = Menu::OPTION_BACK_COLOR_SELECTED_TOP if selected
    color_bottom = Menu::OPTION_BACK_COLOR_SELECTED_BOTTOM if selected
    $game.draw_quad(x, y, color_top, 
                      x + width, y, color_top, 
                      x, y + @height, color_bottom, 
                      x + width, y + @height, color_bottom, ZOrder::Menu)
    
    Menu.font.draw_rel(@text, x + width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 0.5, 0, 1, 1, Menu::OPTION_TEXT_COLOR)
  end
end

class SliderOption < MenuOption
  def initialize(text, start_value, *vars)
    if vars.size == 3
      @min_value, @max_value, @increment = *vars
      @slider_type = :numeric
    else
      @slider_values = vars[0]
      @slider_type = :array
    end
    
    @text, @value = text, start_value
    @selectable = true
    @text_height = Menu::OPTION_TEXT_HEIGHT
    @text_width = Menu.font.text_width(@longest_possible_value || text + ": #{value}")
    @height = Menu::OPTION_TEXT_HEIGHT + Menu::OPTION_HEIGHT_MARGIN * 2
    @min_width = @text_width + Menu::OPTION_WIDTH_MARGIN*4 + Menu::SLIDER_WIDTH*2
  end
  def handle_selection(val)
    case @slider_type
      when :numeric
        @value += val * @increment
        @value = @min_value if @value < @min_value
        @value = @max_value if @value > @max_value
      when :array
        col_i = -1
        @slider_values.each_with_index do |arr_val, i|
          if @value == arr_val
            col_i = i
            break
          end
        end
        @value = @slider_values[col_i + val]
        @value = @slider_values[0] if col_i + val > @slider_values.size - 1
    end
  end
  def draw(x, y, width, selected)
    color_top = Menu::OPTION_BACK_COLOR_TOP if !selected
    color_bottom = Menu::OPTION_BACK_COLOR_BOTTOM if !selected
    color_top = Menu::OPTION_BACK_COLOR_SELECTED_TOP if selected
    color_bottom = Menu::OPTION_BACK_COLOR_SELECTED_BOTTOM if selected
    
    $game.draw_quad(x, y, color_top, 
                      x + width, y, color_top, 
                      x, y + @height, color_bottom, 
                      x + width, y + @height, color_bottom, ZOrder::Menu)
    if @no_display_value
      display_text = @text
    else
      display_text = @text + ": #{@value}"
    end
    Menu.font.draw_rel(display_text, x + width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 0.5, 0, 1, 1, Menu::OPTION_TEXT_COLOR)
    
    $game.draw_triangle(x + Menu::OPTION_WIDTH_MARGIN, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT/2, Menu::SLIDER_COLOR, 
                  x + Menu::OPTION_WIDTH_MARGIN + Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN, Menu::SLIDER_COLOR, 
                  x + Menu::OPTION_WIDTH_MARGIN + Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT, Menu::SLIDER_COLOR, ZOrder::Menu)
    
    $game.draw_triangle(x + width - Menu::OPTION_WIDTH_MARGIN - Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN, Menu::SLIDER_COLOR, 
                  x + width - Menu::OPTION_WIDTH_MARGIN - Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT, Menu::SLIDER_COLOR, 
                  x + width - Menu::OPTION_WIDTH_MARGIN, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT/2, Menu::SLIDER_COLOR, ZOrder::Menu)
    
  end
end

class ToggleOption < MenuOption
  def initialize(text, start_value, on_value, off_value)
    @text, @value, @on_value, @off_value = text, start_value, on_value, off_value
    @selectable = true
    @text_height = Menu::OPTION_TEXT_HEIGHT
    @text_width = Menu.font.text_width(text + ": #{value}")
    @height = Menu::OPTION_TEXT_HEIGHT + Menu::OPTION_HEIGHT_MARGIN * 2
    @min_width = @text_width + Menu::OPTION_WIDTH_MARGIN*4 + Menu::SLIDER_WIDTH*2
  end
  def handle_selection(val)
    @value = @value == @off_value ? @on_value : @off_value
  end
  def draw(x, y, width, selected)
    color_top = Menu::OPTION_BACK_COLOR_TOP if !selected
    color_bottom = Menu::OPTION_BACK_COLOR_BOTTOM if !selected
    color_top = Menu::OPTION_BACK_COLOR_SELECTED_TOP if selected
    color_bottom = Menu::OPTION_BACK_COLOR_SELECTED_BOTTOM if selected
    
    $game.draw_quad(x, y, color_top, 
                      x + width, y, color_top, 
                      x, y + @height, color_bottom, 
                      x + width, y + @height, color_bottom, ZOrder::Menu)
    
    Menu.font.draw_rel(@text + ": #{@value}", x + width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 0.5, 0, 1, 1, Menu::OPTION_TEXT_COLOR)
    
    $game.draw_triangle(x + Menu::OPTION_WIDTH_MARGIN, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT/2, Menu::SLIDER_COLOR, 
                  x + Menu::OPTION_WIDTH_MARGIN + Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN, Menu::SLIDER_COLOR, 
                  x + Menu::OPTION_WIDTH_MARGIN + Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT, Menu::SLIDER_COLOR, ZOrder::Menu)
    
    $game.draw_triangle(x + width - Menu::OPTION_WIDTH_MARGIN - Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN, Menu::SLIDER_COLOR, 
                  x + width - Menu::OPTION_WIDTH_MARGIN - Menu::SLIDER_WIDTH, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT, Menu::SLIDER_COLOR, 
                  x + width - Menu::OPTION_WIDTH_MARGIN, y + Menu::OPTION_HEIGHT_MARGIN + Menu::OPTION_TEXT_HEIGHT/2, Menu::SLIDER_COLOR, ZOrder::Menu)
    
  end
end

class KeepSettingsOption < RegularOption
  def initialize
    super("Keep these settings ()")
  end
  def handle_selection(val)
    $game.menu.deactivate_settings_check_timer
  end
end

class ResumeGameOption < RegularOption
  def initialize
    super("Resume game")
  end
  def handle_selection(val)
    $game.resume_game
    nil
  end
end

class InstructionsOption < RegularOption
  def initialize
    super("Instructions")
  end
  def handle_selection(val)
    options = []
    options << ImageOption.new("media/instructions1.png")
    options << NextInstructionsOption.new
    options << BackOption.new
    $game.menu.new_options options
  end
end

class NextInstructionsOption < RegularOption
  def initialize
    super("Next")
  end
  def handle_selection(val)
    $game.menu.back
    options = []
    options << ImageOption.new("media/instructions2.png")
    options << BackOption.new
    $game.menu.new_options options
  end
end

class AboutOption < RegularOption
  def initialize
    super("About")
  end
  def handle_selection(val)
    options = []
    options << AboutTextOption.new
    options << BackOption.new
    $game.menu.new_options options
  end
end

class ImageOption < RegularOption
  def initialize(img)
    @selectable = false
    @image = Images[img]
    @height = @image.height + Menu::OPTION_HEIGHT_MARGIN * 2
    @min_width = @image.width + Menu::OPTION_WIDTH_MARGIN * 2
  end
  def draw(x, y, width, selected)
    @image.draw(x + width / 2 - @image.width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu)
  end
end

class AboutTextOption < RegularOption
  def initialize
    @selectable = false
    @normal_text_height = 16
    @large_text_multiplier = 2
    @font = Gosu::Font.new($game, Gosu::default_font_name, @normal_text_height)
    @text_margin = 6
    @text = []
    @text_formatting = []
    @text << "Rock, Paper, Grenade"
    @text_formatting << ["large", "centered"]
    @text << "by Michael Keenan"
    @text_formatting << ["centered"]
    @text << ""
    @text << "Version 0.1"
    @text << ""
    @text << "Thanks to:"
    @text << "Julian Raschke for the awesome Gosu game development library"
    @text << "Janis Born for the graphics, sound and particle code I borrowed from him"
    @text << "Holly McArthur for playtesting"
    @text << "Firelight Technologies for the FMOD audio library"
    @text << "Matz and the team for Ruby"
    @text << ""
    @text << "Contact michael.keenan@gmail.com"
    
    @height = calc_height
    @min_width = calc_width
  end
  def calc_height
    ret = @text_margin
    @text.each_with_index do |t, i|
      if @text_formatting[i] and @text_formatting[i].include?("large")
        ret += @large_text_multiplier * @normal_text_height
      else
        ret += @normal_text_height
      end
      ret += @text_margin
    end
    ret
  end
  def calc_width
    ret = 0
    @text.each_with_index do |t, i|
      if @text_formatting[i] and @text_formatting[i].include?("large")
        ret = @large_text_multiplier * @font.text_width(t) if @large_text_multiplier * @font.text_width(t) > ret
      else
        ret = @font.text_width(t) if @font.text_width(t) > ret
      end
    end
    ret
  end
  def draw(x, y, width, selected)
    temp_y = y + @text_margin
    @text.each_with_index do |t, i|
      factor = 1
      rel_x = 0
      temp_x = x + @text_margin
      if @text_formatting[i]
        factor = @large_text_multiplier if @text_formatting[i].include?("large")
        rel_x = 0.5 if @text_formatting[i].include?("centered")
        temp_x += width/2 - @text_margin
      end
      @font.draw_rel(t, temp_x, temp_y, ZOrder::Menu, rel_x, 0, factor, factor)
      temp_y += factor * @normal_text_height + @text_margin
    end
  end
end

class OptionsOption < RegularOption
  def initialize
    super("Options")
  end
  def handle_selection(val)
    options = []
    options << ScreenWidthOption.new
    options << ScreenHeightOption.new
    options << FullScreenOption.new
    options << SoundVolumeOption.new
    options << BackOption.new
    $game.menu.new_options options
  end
end

class ExitOption < RegularOption
  def initialize
    super("Exit")
  end
  def handle_selection(val)
    $game.close
  end
end

class BackOption < RegularOption
  def initialize
    super("Back")
  end
  def handle_selection(val)
    GameConfig.save_options_to_file
    $game.menu.back
  end
end

class UnitDisplayOption < MenuOption
  def initialize(unit_index)
    @unit_index = unit_index
    @selectable = false
    @image_uniform = Anims["media/unit_uniform.png"][0]
    @image_skin = Anims["media/unit_skin.png"][0]
    @height = @image_uniform.height + Menu::OPTION_HEIGHT_MARGIN * 2
    @min_width = @image_uniform.width + Menu::OPTION_WIDTH_MARGIN * 2
  end
  def draw(x, y, width, selected)
    @image_skin.draw(x + width / 2 - @image_skin.width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 1, 1, GameConfig["unit#{@unit_index}_skin_color"])
    @image_uniform.draw(x + width / 2 - @image_uniform.width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 1, 1, GameConfig["unit#{@unit_index}_uniform_color"])
  end
end

class UnitColorOption < SliderOption
  def initialize(unit_index)
    @unit_index = unit_index
    @no_display_value = true
    start_value = GameConfig["unit#{@unit_index}_uniform_color"]
    super("Color", start_value, $game.colors)
  end
  def handle_selection(val)
    super(val)
    if $game.taken_colors.include?(@value)
      handle_selection(val)
    end
    GameConfig["unit#{@unit_index}_uniform_color"] = @value
  end
end

class UnitHealthOption < SliderOption
  def initialize(unit_index)
    @unit_index = unit_index
    start_value = GameConfig["unit#{@unit_index}_health"]
    super("Health", start_value, 50, 200, 10)
  end
  def handle_selection(val)
    super(val)
    GameConfig["unit#{@unit_index}_health"] = @value
  end
end

class UnitControllerOption < SliderOption
  def initialize(unit_index)
    @unit_index = unit_index
    start_value = GameConfig["unit#{@unit_index}_controller"]
    super("Controller", start_value, $game.controllers)
  end
  def handle_selection(val)
    super(val)
    if $game.taken_controllers.include?(@value)
      handle_selection(val)
    end
    GameConfig["unit#{@unit_index}_controller"] = @value
  end
end

class UnitTeamOption < SliderOption
  def initialize(unit_index)
    @unit_index = unit_index
    start_value = GameConfig["unit#{@unit_index}_team"]
    super("Team", start_value, (1..8).to_a)
  end
  def handle_selection(val)
    super(val)
    GameConfig["unit#{@unit_index}_team"] = @value
  end
end

class NewGameOption < RegularOption
  def initialize
    super("New game")
  end
  def handle_selection(val)
    options = [StartGameOption.new]
    options << PointLimitOption.new
    #options << GameTypeOption.new
    Game::MAX_PLAYERS.times do |n|
      options << EditPlayerOption.new(n)
    end
    options << StartGameOption.new
    options << BackOption.new
    $game.menu.new_options options
    $game.menu.show_player_summary
  end
end

class StartGameOption < RegularOption
  def initialize
    super("Start game")
  end
  def handle_selection(val)
    $game.start_game
    nil
  end
end

class GameTypeOption < SliderOption
  def initialize
    start_value = GameConfig["game_type"]
    longest_word = ""
    $game.game_types.each do |s|
      if s.length > longest_word.length
        longest_word = s
      end
    end
    @longest_possible_value = "Type: #{longest_word}"
    super("Type", start_value, $game.game_types)
    
  end
  def handle_selection(val)
    super(val)
    GameConfig["game_type"] = @value
    nil
  end
end

class EditPlayerOption < RegularOption
  def initialize(unit_index)
    @unit_index = unit_index
    super("Edit player #{@unit_index + 1}")
  end
  def handle_selection(val)
    options = [UnitDisplayOption.new(@unit_index)]
    options << UnitControllerOption.new(@unit_index)
    options << UnitColorOption.new(@unit_index)
    options << UnitTeamOption.new(@unit_index)
    options << UnitHealthOption.new(@unit_index)
    options << BackOption.new
    $game.menu.new_options options
    $game.menu.show_player_summary
  end
end

class ScreenWidthOption < SliderOption
  def initialize
    start_value = GameConfig["screen_width"]
    super("Screen width", start_value, $game.screen_widths)
    @help = ["This sets the width of the game arena (it does not set your screen's resolution).", 
      "High values for game width will stretch across multiple monitors (if you have them).", 
      "Changing this option will end any games currently in progress.", 
      "Some combinations of full screen mode and high screen width or height can cause problems.", 
      "You will be asked to confirm the setting when the game restarts.", 
      "If you don't see anything, the game will restart with safe settings in a few seconds."].reverse
  end
  def handle_selection(val)
    super(val)
    $game.menu.restart
    GameConfig["screen_width"] = @value
  end
end

class ScreenHeightOption < SliderOption
  def initialize
    start_value = GameConfig["screen_height"]
    super("Screen height", start_value, $game.screen_heights)
    @help = ["This sets the height of the game arena (it does not set your screen's resolution).", 
      "Changing this option will end any games currently in progress.", 
      "Some combinations of full screen mode and high screen width or height can cause problems.", 
      "You will be asked to confirm the setting when the game restarts.", 
      "If you don't see anything, the game will restart with safe settings in a few seconds."].reverse
  end
  def handle_selection(val)
    super(val)
    $game.menu.restart
    GameConfig["screen_height"] = @value
  end
end

class FullScreenOption < ToggleOption
  def initialize
    start_value = GameConfig["fullscreen"]
    super("Full screen", start_value, "Yes", "No")
    @help = ["This toggles whether the game runs in full screen mode.", 
      "Changing this option will end any games currently in progress.", 
      "Some combinations of full screen mode and high screen width or height can cause problems.", 
      "You will be asked to confirm the setting when the game restarts.", 
      "If you don't see anything, the game will restart with safe settings in a few seconds."].reverse
  end
  def handle_selection(val)
    super(val)
    $game.menu.restart
    GameConfig["fullscreen"] = @value
  end
end

class SoundVolumeOption < SliderOption
  def initialize
    start_value = GameConfig["sound_volume"]
    super("Sound volume", start_value, 0, 10, 1)
  end
  def handle_selection(val)
    super(val)
    GameConfig["sound_volume"] = @value
  end
end

class QuickStartOption < RegularOption
  def initialize
    super("Quick start")
  end
  def handle_selection(val)
    options = []
    options << PointLimitOption.new
    options << OneVsOneComputerOption.new
    options << OneVsOneHumanOption.new
    options << OneHumanOneCompVsTwoOption.new
    options << TwoVsTwoOption.new
    options << BackOption.new
    $game.menu.new_options options
  end
end

class PointLimitOption < SliderOption
  def initialize
    start_value = GameConfig["point_limit"]
    super("Point limit", start_value, [1, 5, 10, 15, 20])
  end
  def handle_selection(val)
    super(val)
    GameConfig["point_limit"] = @value
  end
end

class OneVsOneComputerOption < RegularOption
  def initialize
    super("One human vs. one computer")
  end
  def handle_selection(val)
    GameConfig["unit0_controller"] = "Human (left)"
    GameConfig["unit0_health"] = 100
    GameConfig["unit0_team"] = 1
    GameConfig["unit1_controller"] = "Computer"
    GameConfig["unit1_health"] = 100
    GameConfig["unit1_team"] = 2
    GameConfig["unit2_controller"] = "None"
    GameConfig["unit3_controller"] = "None"
    GameConfig["unit4_controller"] = "None"
    GameConfig["unit5_controller"] = "None"
    GameConfig["unit6_controller"] = "None"
    GameConfig["unit7_controller"] = "None"
    $game.start_game
    nil
  end
end

class OneVsOneHumanOption < RegularOption
  def initialize
    super("One human vs. one human")
  end
  def handle_selection(val)
    GameConfig["unit0_controller"] = "Human (left)"
    GameConfig["unit0_health"] = 100
    GameConfig["unit0_team"] = 1
    GameConfig["unit1_controller"] = "Human (right)"
    GameConfig["unit1_health"] = 100
    GameConfig["unit1_team"] = 2
    GameConfig["unit2_controller"] = "None"
    GameConfig["unit3_controller"] = "None"
    GameConfig["unit4_controller"] = "None"
    GameConfig["unit5_controller"] = "None"
    GameConfig["unit6_controller"] = "None"
    GameConfig["unit7_controller"] = "None"
    $game.start_game
    nil
  end
end

class OneHumanOneCompVsTwoOption < RegularOption
  def initialize
    super("One human and one computer vs. two computers")
  end
  def handle_selection(val)
    GameConfig["unit0_controller"] = "Human (left)"
    GameConfig["unit0_health"] = 100
    GameConfig["unit0_team"] = 1
    GameConfig["unit1_controller"] = "Computer"
    GameConfig["unit1_health"] = 100
    GameConfig["unit1_team"] = 1
    GameConfig["unit2_controller"] = "Computer"
    GameConfig["unit2_health"] = 100
    GameConfig["unit2_team"] = 2
    GameConfig["unit3_controller"] = "Computer"
    GameConfig["unit3_health"] = 100
    GameConfig["unit3_team"] = 2
    GameConfig["unit4_controller"] = "None"
    GameConfig["unit5_controller"] = "None"
    GameConfig["unit6_controller"] = "None"
    GameConfig["unit7_controller"] = "None"
    $game.start_game
    nil
  end
end

class TwoVsTwoOption < RegularOption
  def initialize
    super("Two humans vs. two computers")
  end
  def handle_selection(val)
    GameConfig["unit0_controller"] = "Human (left)"
    GameConfig["unit0_health"] = 100
    GameConfig["unit0_team"] = 1
    GameConfig["unit1_controller"] = "Human (right)"
    GameConfig["unit1_health"] = 100
    GameConfig["unit1_team"] = 1
    GameConfig["unit2_controller"] = "Computer"
    GameConfig["unit2_health"] = 100
    GameConfig["unit2_team"] = 2
    GameConfig["unit3_controller"] = "Computer"
    GameConfig["unit3_health"] = 100
    GameConfig["unit4_team"] = 2
    GameConfig["unit4_controller"] = "None"
    GameConfig["unit5_controller"] = "None"
    GameConfig["unit6_controller"] = "None"
    GameConfig["unit7_controller"] = "None"
    $game.start_game
    nil
  end
end

class TeamWonOption < MenuOption
  def initialize
    @selectable = false
    @winner = $game.winning_team
    @height = Menu::OPTION_TEXT_HEIGHT * 2 + Menu::OPTION_HEIGHT_MARGIN * 2
    @text = "Team #{@winner} wins!"
    @text_width = Menu.font.text_width("Team #{@winner} wins!") * 2
    @min_width = @text_width + Menu::OPTION_WIDTH_MARGIN * 2
  end
  def draw(x, y, width, selected)
    Menu.font.draw_rel(@text, x + width/2, y + Menu::OPTION_HEIGHT_MARGIN, ZOrder::Menu, 0.5, 0, 2, 2)
  end
end

class ScoreboardOption < MenuOption
  def initialize
    @selectable = false
    @winner = $game.winning_team
    @height = $game.teams.size * 24 + Menu::OPTION_HEIGHT_MARGIN * 2
    @text_width = Menu.font.text_width("Team 00: 00")
    @min_width = @text_width + Menu::OPTION_WIDTH_MARGIN * 2
  end
  def draw(x, y, width, selected)
    temp_x, temp_y = x, y
    $game.teams.each do |n|
      Menu.font.draw_rel("Team #{n}: ", temp_x + width/2, temp_y, ZOrder::Menu, 1, 0, 1, 1)
      Menu.font.draw_rel(" #{$game.team_scores[n]}", temp_x + width/2, temp_y, ZOrder::Menu, 0, 0, 1, 1)
      temp_y += 24
    end
  end
end

class GameOverBackOption < BackOption
  def initialize
    super
  end
  def handle_selection(val)
    $game.end_game
    super(val)
  end
end
